home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 2000 November: Tool Chest / Dev.CD Nov 00 TC Disk 2.toast / pc / sample code / quicktime / effects / makeeffectslideshow / application files / comapplication.c next >
Encoding:
Text File  |  2000-09-28  |  14.7 KB  |  562 lines

  1. //////////
  2. //
  3. //    File:        ComApplication.c
  4. //
  5. //    Contains:    Application-specific code for basic VR movie display and control.
  6. //                This file is used for BOTH MacOS and Windows.
  7. //
  8. //    Written by:    Tim Monroe
  9. //                Based (heavily!) on the MovieShell code written by Apple DTS.
  10. //
  11. //    Copyright:    © 1994-1997 by Apple Computer, Inc., all rights reserved.
  12. //
  13. //    Change History (most recent first):
  14. //
  15. //       <14>         12/16/98    rtm        removed all QTVR API calls, so we can remove QTVR.lib from project
  16. //       <13>         02/28/98    rtm        reworked DoApplicationEventLoopAction
  17. //       <12>         11/24/97    rtm        added code to DoApplicationEventLoopAction to handle effects dialog events
  18. //       <11>         11/06/97    rtm        removed QTVR support; added support for MakeEffectMovie routines;
  19. //                                    added AppleEvent support
  20. //       <10>         10/23/97    rtm        moved InitializeQTVR to InitApplication, TerminateQTVR to StopApplication
  21. //       <9>         10/13/97    rtm        reworked HandleApplicationMenu to use menu identifiers
  22. //       <8>         09/11/97    rtm        merged MacApplication.c and WinApplication.c into ComApplication.c
  23. //       <7>         08/21/97    rtm        first file for Windows; based on MacApplication.c for Mac sample code
  24. //       <6>         06/04/97    rtm        removed call to QTVRUtils_IsQTVRMovie in InitApplicationWindowObject
  25. //       <5>         02/06/97    rtm        fixed window resizing code
  26. //       <4>         12/05/96    rtm        added hooks into MacFramework.c: StopApplication, InitApplicationWindowObject
  27. //       <3>         12/02/96    rtm        added cursor updating to DoIdle
  28. //       <2>         11/27/96    rtm        conversion to personal coding style; added preliminary QTVR support
  29. //       <1>         12/21/94    khs        first file
  30. //       
  31. //////////
  32.  
  33. // header files
  34. #include "ComApplication.h"
  35. #include "MakeEffectSlideShow.h"
  36.  
  37. // global variables for Macintosh code
  38. #if TARGET_OS_MAC
  39. AEEventHandlerUPP            gHandleOpenAppAEUPP;                // UPPs for our Apple event handlers
  40. AEEventHandlerUPP            gHandleOpenDocAEUPP;
  41. AEEventHandlerUPP            gHandlePrintDocAEUPP;
  42. AEEventHandlerUPP            gHandleQuitAppAEUPP;
  43. #endif
  44.  
  45. // global variables for Windows code
  46. #if TARGET_OS_WIN32
  47. extern HWND                    ghWnd;                                // the MDI frame window; this window has the menu bar
  48. extern int                    gNumWindowsOpen;
  49. extern Boolean                gShuttingDown;
  50. extern LPSTR                gCmdLine;
  51. #endif
  52.  
  53. long                        gMaxMilliSecToUse = 0L;    
  54.     
  55. // external variables
  56. extern Boolean                gAppInForeground;                    // is our application in the foreground?    
  57. extern QTParameterDialog    gEffectsDialog;
  58.  
  59.  
  60. //////////
  61. //
  62. // InitApplication
  63. // Do any application-specific initialization.
  64. //
  65. // The theStartPhase parameter determines which "phase" of application start-up is executed,
  66. // *before* the MDI frame window is created or *after*. This distinction is relevant only on
  67. // Windows, so on MacOS, you should always use kInitAppPhase_BothPhases.
  68. //
  69. //////////
  70.  
  71. void InitApplication (UInt32 theStartPhase)
  72. {
  73.     // •••do any start-up activities that should occur before the MDI frame window is created
  74.     if (theStartPhase & kInitAppPhase_BeforeCreateFrameWindow) {
  75.  
  76.         // check to make sure that QuickTime video effects are available;
  77.         // we depend on these features  
  78.         if (!QTUtils_HasQuickTimeVideoEffects())
  79.             QuitFramework();
  80.             
  81. #if TARGET_OS_MAC
  82.         // make sure that the Apple Event Manager is available; install handlers for required Apple events
  83.         InstallAppleEventHandlers();
  84. #endif
  85.     }    // end of kInitAppPhase_BeforeCreateFrameWindow
  86. }
  87.  
  88.  
  89. //////////
  90. //
  91. // StopApplication
  92. // Do any application-specific shut-down.
  93. //
  94. // The theStopPhase parameter determines which "phase" of application shut-down is executed,
  95. // *before* any open movie windows are destroyed or *after*.
  96. //
  97. //////////
  98.  
  99. void StopApplication (UInt32 theStopPhase)
  100. {
  101.     // do any shut-down activities that should occur after the movie windows are destroyed
  102.     if (theStopPhase & kStopAppPhase_AfterDestroyWindows) {
  103. #if TARGET_OS_MAC
  104.         // dispose of routine descriptors for Apple event handlers
  105.         DisposeRoutineDescriptor(gHandleOpenAppAEUPP);
  106.         DisposeRoutineDescriptor(gHandleOpenDocAEUPP);
  107.         DisposeRoutineDescriptor(gHandlePrintDocAEUPP);
  108.         DisposeRoutineDescriptor(gHandleQuitAppAEUPP);
  109. #endif
  110.     }    // end of kStopAppPhase_AfterDestroyWindows
  111. }
  112.  
  113.  
  114. //////////
  115. //
  116. // DoIdle
  117. // Do any processing that can/should occur at idle time.
  118. //
  119. //////////
  120.  
  121. void DoIdle (WindowReference theWindow)
  122. {
  123.     WindowObject         myWindowObject = NULL;
  124.     GrafPtr             mySavedPort;
  125.     
  126.     GetPort(&mySavedPort);
  127.     MacSetPort(GetPortFromWindowReference(theWindow));
  128.     
  129.     myWindowObject = GetWindowObjectFromWindow(theWindow);
  130.     if (myWindowObject != NULL) {
  131.         MovieController        myMC = NULL;
  132.     
  133.         myMC = (**myWindowObject).fController;
  134.         if (myMC != NULL) {
  135.  
  136. #if TARGET_OS_MAC
  137.             // restore the cursor to the arrow
  138.             // if it's outside the front movie window or outside the window's visible region
  139.             if (theWindow == GetFrontMovieWindow()) {
  140.                 Rect    myRect;
  141.                 Point    myPoint;
  142.                 
  143.                 GetMouse(&myPoint);
  144.                 MCGetControllerBoundsRect(myMC, &myRect);
  145.                 if (!MacPtInRect(myPoint, &myRect) || !PtInRgn(myPoint, GetPortFromWindowReference(theWindow)->visRgn))
  146.                     MacSetCursor(&qd.arrow);
  147.             }
  148. #endif    // TARGET_OS_MAC
  149.         }
  150.     }
  151.     
  152.     // @@@INSERT APPLICATION-SPECIFIC IDLE-TIME FUNCTIONALITY HERE
  153.     
  154.     MacSetPort(mySavedPort);
  155. }
  156.  
  157.  
  158. //////////
  159. //
  160. // DoUpdateWindow
  161. // Update the specified window.
  162. //
  163. //////////
  164.  
  165. void DoUpdateWindow (WindowReference theWindow, Rect *theRefreshArea)
  166. {
  167.     GrafPtr             mySavedPort;
  168.     
  169.     GetPort(&mySavedPort);
  170.     MacSetPort(GetPortFromWindowReference(theWindow));
  171.     
  172.     BeginUpdate(GetPortFromWindowReference(theWindow));
  173.     
  174.     // draw the movie controller and its movie
  175.     MCDoAction(GetMCFromWindow(theWindow), mcActionDraw, theWindow);
  176.     
  177.     EndUpdate(GetPortFromWindowReference(theWindow));
  178.     MacSetPort(mySavedPort);
  179. }
  180.  
  181.  
  182. //////////
  183. //
  184. // HandleContentClick
  185. // Handle mouse button clicks in the specified window.
  186. //
  187. //////////
  188.  
  189. void HandleContentClick (WindowReference theWindow, EventRecord *theEvent)
  190. {
  191. #pragma unused(theEvent)
  192.  
  193.     GrafPtr             mySavedPort;
  194.     
  195.     GetPort(&mySavedPort);
  196.     MacSetPort(GetPortFromWindowReference(theWindow));
  197.     
  198.     // @@@INSERT APPLICATION-SPECIFIC CONTENT CLICKING FUNCTIONALITY HERE
  199.  
  200.     MacSetPort(mySavedPort);
  201. }
  202.  
  203.  
  204. //////////
  205. //
  206. // HandleApplicationKeyPress
  207. // Handle application-specific key presses.
  208. // Returns true if the key press was handled, false otherwise.
  209. //
  210. //////////
  211.  
  212. Boolean HandleApplicationKeyPress (char theCharCode)
  213. {
  214.     Boolean        isHandled = true;
  215.     
  216.     switch (theCharCode) {
  217.     
  218.         // @@@HANDLE APPLICATION-SPECIFIC KEY PRESSES HERE
  219.  
  220.         default:
  221.             isHandled = false;
  222.             break;
  223.     }
  224.  
  225.     return(isHandled);
  226. }
  227.  
  228.  
  229. #if TARGET_OS_MAC
  230. //////////
  231. //
  232. // CreateMovieWindow
  233. // Create a window to display a movie in.
  234. //
  235. //////////
  236.  
  237. WindowRef CreateMovieWindow (Rect *theRect, Str255 theTitle)
  238. {
  239.     WindowRef            myWindow;
  240.         
  241.     myWindow = NewCWindow(NULL, theRect, theTitle, false, noGrowDocProc, (WindowPtr)-1L, true, 0);
  242.     return(myWindow);
  243. }
  244. #endif
  245.  
  246.  
  247. //////////
  248. //
  249. // HandleApplicationMenu
  250. // Handle selections in the application's menus.
  251. //
  252. // The theMenuItem parameter is a UInt16 version of the Windows "menu item identifier". 
  253. // When called from Windows, theMenuItem is simply the menu item identifier passed to the window proc.
  254. // When called from MacOS, theMenuItem is constructed like this:
  255. //     *high-order 8 bits == the Macintosh menu ID (1 thru 256)
  256. //     *low-order 8 bits == the Macintosh menu item (sequential from 1 to ordinal of last menu item in menu)
  257. // In this way, we can simplify the menu-handling code. There are, however, some limitations,
  258. // mainly that the menu item identifiers on Windows must be derived from the Mac values. 
  259. //
  260. //////////
  261.  
  262. void HandleApplicationMenu (UInt16 theMenuItem)
  263. {
  264.     switch (theMenuItem) {
  265.         case IDM_MAKE_EFFECT_MOVIE:
  266.             // ask the user for some movies and an effect,
  267.             // but only if the effects dialog isn't showing already
  268.             if (gEffectsDialog == 0L)
  269.                 QTEffects_PromptUserForFilesAndMakeEffect();
  270.             break;
  271.  
  272.         default:
  273.             break;
  274.     } // switch (theMenuItem)
  275. }
  276.  
  277.  
  278. //////////
  279. //
  280. // AdjustApplicationMenus
  281. // Adjust state of items in the application's menus.
  282. //
  283. // Currently, the Mac application has only one app-specific menu ("Test"); you could change that.
  284. //
  285. //////////
  286.  
  287. void AdjustApplicationMenus (WindowReference theWindow, MenuReference theMenu)
  288. {
  289. #pragma unused(theWindow)
  290.     MenuReference            myMenu;
  291.     
  292. #if TARGET_OS_WIN32
  293.     myMenu = theMenu;
  294. #elif TARGET_OS_MAC
  295.     myMenu = GetMenuHandle(kTestMenu);
  296. #endif
  297.     
  298.     // we don't allow creating new files here...
  299. #if TARGET_OS_MAC
  300.     SetMenuItemState(GetMenuHandle(mFile), iNew, kDisableMenuItem);
  301. #endif
  302.  
  303.     // if effects dialog is already open, don't allow user to select more files
  304.     if (gEffectsDialog != 0)
  305.         SetMenuItemState(myMenu, IDM_MAKE_EFFECT_MOVIE, kDisableMenuItem);
  306.     else
  307.         SetMenuItemState(myMenu, IDM_MAKE_EFFECT_MOVIE, kEnableMenuItem);
  308. }
  309.  
  310.  
  311. //////////
  312. //
  313. // DoApplicationEventLoopAction
  314. // Perform any application-specific event loop actions.
  315. //
  316. // Return true to indicate that we've completely handled the event here, false otherwise.
  317. //
  318. //////////
  319.  
  320. Boolean DoApplicationEventLoopAction (EventRecord *theEvent)
  321. {
  322.     Boolean        isHandled = false;
  323.     
  324.     // see if the event is meant for the effects parameter dialog box
  325.     if (gEffectsDialog != 0L)
  326.         isHandled = QTEffects_HandleEffectsDialogEvents(theEvent, 0);
  327.  
  328.     return(isHandled);
  329. }
  330.  
  331.  
  332. //////////
  333. //
  334. // AddControllerFunctionality
  335. // Configure the movie controller.
  336. //
  337. //////////
  338.  
  339. void AddControllerFunctionality (MovieController theMC)
  340. {
  341.     long            myControllerFlags;
  342.     
  343.     // CLUT table use    
  344.     MCDoAction(theMC, mcActionGetFlags, &myControllerFlags);
  345.     MCDoAction(theMC, mcActionSetFlags, (void *)(myControllerFlags | mcFlagsUseWindowPalette));
  346.  
  347.     // enable keyboard event handling    
  348.     MCDoAction(theMC, mcActionSetKeysEnabled, (void *)true);
  349.     
  350.     // disable drag support
  351.     MCDoAction(theMC, mcActionSetDragEnabled, (void *)false);
  352. }
  353.  
  354.  
  355. //////////
  356. //
  357. // InitApplicationWindowObject
  358. // Do any application-specific initialization of the window object.
  359. //
  360. //////////
  361.  
  362. void InitApplicationWindowObject (WindowObject theWindowObject)
  363. {
  364. #pragma unused(theWindowObject)
  365. }
  366.  
  367.  
  368. //////////
  369. //
  370. // RemoveApplicationWindowObject
  371. // Do any application-specific clean-up of the window object.
  372. //
  373. //////////
  374.  
  375. void RemoveApplicationWindowObject (WindowObject theWindowObject)
  376. {
  377. #pragma unused(theWindowObject)
  378.     // DoDestroyMovieWindow in MacFramework.c or MovieWndProc in WinFramework.c
  379.     // releases the window object itself
  380. }
  381.  
  382.  
  383. //////////
  384. //
  385. // ApplicationMCActionFilterProc 
  386. // Intercept some mc actions for the movie controller.
  387. //
  388. // NOTE: The theRefCon parameter is a handle to a window object record.
  389. //
  390. //////////
  391.  
  392. PASCAL_RTN Boolean ApplicationMCActionFilterProc (MovieController theMC, short theAction, void *theParams, long theRefCon)
  393. {
  394. #pragma unused(theMC, theParams)
  395.  
  396.     Boolean                isHandled = false;
  397.     WindowObject        myWindowObject = NULL;
  398.     
  399.     myWindowObject = (WindowObject)theRefCon;
  400.     if (myWindowObject == NULL)
  401.         return(isHandled);
  402.         
  403.     switch (theAction) {
  404.     
  405.         // handle window resizing
  406.         case mcActionControllerSizeChanged:
  407.             SizeWindowToMovie(myWindowObject);
  408.             break;
  409.  
  410.         // handle idle events
  411.         case mcActionIdle:
  412.             DoIdle((**myWindowObject).fWindow);
  413.             break;
  414.             
  415.         default:
  416.             break;
  417.             
  418.     }    // switch (theAction)
  419.     
  420.     return(isHandled);    
  421. }
  422.  
  423.  
  424. #if TARGET_OS_MAC
  425. //////////
  426. //
  427. // InstallAppleEventHandlers 
  428. // Install handlers for Apple events.
  429. //
  430. //////////
  431.  
  432. void InstallAppleEventHandlers (void)
  433. {
  434.     OSErr        myErr;
  435.     long        myAttrs;
  436.     
  437.     // see whether the Apple Event Manager is available in the present operating environment;
  438.     // if it is, install handlers for the four required Apple events
  439.     myErr = Gestalt(gestaltAppleEventsAttr, &myAttrs);
  440.     if (myErr == noErr) {
  441.         if (myAttrs & (1L << gestaltAppleEventsPresent)) {
  442.             // create routine descriptors for the Apple event handlers
  443.             gHandleOpenAppAEUPP = NewAEEventHandlerProc(HandleOpenApplicationAppleEvent);
  444.             gHandleOpenDocAEUPP = NewAEEventHandlerProc(HandleOpenDocumentAppleEvent);
  445.             gHandlePrintDocAEUPP = NewAEEventHandlerProc(HandlePrintDocumentAppleEvent);
  446.             gHandleQuitAppAEUPP = NewAEEventHandlerProc(HandleQuitApplicationAppleEvent);
  447.             
  448.             // install the handlers
  449.             AEInstallEventHandler(kCoreEventClass, kAEOpenApplication, gHandleOpenAppAEUPP, 0L, false);
  450.             AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments, gHandleOpenDocAEUPP, 0L, false);
  451.             AEInstallEventHandler(kCoreEventClass, kAEPrintDocuments, gHandlePrintDocAEUPP, 0L, false);
  452.             AEInstallEventHandler(kCoreEventClass, kAEQuitApplication, gHandleQuitAppAEUPP, 0L, false);
  453.         }
  454.     }
  455. }
  456.         
  457.         
  458. //////////
  459. //
  460. // HandleOpenApplicationAppleEvent 
  461. // Handle the open-application Apple event.
  462. //
  463. //////////
  464.  
  465. pascal OSErr HandleOpenApplicationAppleEvent (const AppleEvent *theMessage, const AppleEvent *theReply, long theRefcon)            
  466. {
  467. #pragma unused(theMessage, theReply, theRefcon)
  468.  
  469.     // we don't need to do anything special when opening the application
  470.     return(noErr);
  471. }
  472.  
  473.  
  474. //////////
  475. //
  476. // HandleOpenDocumentAppleEvent 
  477. // Handle the open-document Apple event. This is based on Inside Macintosh: IAC, pp. 4-15f.
  478. //
  479. //////////
  480.  
  481. pascal OSErr HandleOpenDocumentAppleEvent (const AppleEvent *theMessage, const AppleEvent *theReply, long theRefcon)            
  482. {
  483. #pragma unused(theReply, theRefcon)
  484.  
  485.     long            myIndex;
  486.     long            myItemsInList;
  487.     AEKeyword        myKeyWd;
  488.     OSErr            myErr;
  489.     OSErr            myIgnoreErr;
  490.     AEDescList          myDocList;
  491.     long            myActualSize;
  492.     DescType        myTypeCode;
  493.     FSSpec            myFSSpec;
  494.     FSSpec            myFSSpecList[kMaxNumSources];
  495.     UInt16            myFSSpecCount = 0;
  496.     
  497.     // get the direct parameter and put it into myDocList
  498.     myDocList.dataHandle = NULL;
  499.     myErr = AEGetParamDesc(theMessage, keyDirectObject, typeAEList, &myDocList);
  500.     
  501.     // count the descriptor records in the list
  502.     if (myErr == noErr)
  503.         myErr = AECountItems(&myDocList, &myItemsInList);
  504.     else
  505.         myItemsInList = 0;
  506.     
  507.     // open each specified file
  508.     for (myIndex = 1; myIndex <= myItemsInList; myIndex++)
  509.         if (myErr == noErr) {
  510.             myErr = AEGetNthPtr(&myDocList, myIndex, typeFSS, &myKeyWd, &myTypeCode, (Ptr)&myFSSpec, sizeof(myFSSpec), &myActualSize);
  511.             if ((myErr == noErr) && (myFSSpecCount < kMaxNumSources)) {
  512.                 myFSSpecList[myFSSpecCount] = myFSSpec;
  513.                 myFSSpecCount++;
  514.             }
  515.         }
  516.  
  517.     if (myDocList.dataHandle)
  518.         myIgnoreErr = AEDisposeDesc(&myDocList);
  519.     
  520.     if (myErr == noErr)
  521.         myErr = QTEffects_DisplayDialogForSources(myFSSpecList, myFSSpecCount);
  522.     
  523.     // make sure we open the document in the foreground        
  524.     gAppInForeground = true;
  525.     return(myErr);
  526. }
  527.  
  528.  
  529. //////////
  530. //
  531. // HandlePrintDocumentAppleEvent 
  532. // Handle the print-document Apple event.
  533. //
  534. //////////
  535.  
  536. pascal OSErr HandlePrintDocumentAppleEvent (const AppleEvent *theMessage, const AppleEvent *theReply, long theRefcon)            
  537. {
  538. #pragma unused(theMessage, theReply, theRefcon)
  539.     QuitFramework();
  540.     return(errAEEventFailed);
  541. }
  542.  
  543.  
  544. //////////
  545. //
  546. // HandleQuitApplicationAppleEvent 
  547. // Handle the quit-application Apple event.
  548. //
  549. //////////
  550.  
  551. pascal OSErr HandleQuitApplicationAppleEvent (const AppleEvent *theMessage, const AppleEvent *theReply, long theRefcon)            
  552. {
  553. #pragma unused(theMessage, theReply, theRefcon)
  554.  
  555.     // close down the entire framework and application
  556.     QuitFramework();
  557.     return(noErr);
  558. }
  559. #endif    // TARGET_OS_MAC
  560.  
  561.  
  562.